package dao

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/google/uuid"
	"order_srv/basic/config"
	inits "order_srv/basic/init"
	__ "order_srv/basic/orderproto"
	"order_srv/handler/models"
	"order_srv/untils"
	"time"
)

// 创建导出任务（优化版）
func CreateExportTaskV2(in *__.ExportOrderReq) (*models.ExportTask, error) {
	//1.参数校验
	if err := validateExportRequest(in); err != nil {
		return nil, err
	}

	//2.解析时间
	startTime, endTime, err := parseTimeRange(in.StartTime, in.EndTime)
	if err != nil {
		return nil, fmt.Errorf("时间解析失败:%v", err)
	}

	//3.检查数据量限制
	if err = checkDataVolumeLimit(startTime, endTime, int8(in.OrderType), in.MaxRecords); err != nil {
		return nil, err
	}

	//4.创建任务记录
	task := &models.ExportTask{
		TaskId:         uuid.NewString(),
		UserId:         uint32(in.UserId),
		Status:         0,
		TaskType:       1,
		ExportFormat:   getExportFormat(in.ExportFormat),
		Priority:       getPriority(in.Priority),
		MaxRecords:     uint32(in.MaxRecords),
		StartTime:      startTime,
		EndTime:        endTime,
		FilterParams:   in.FilterParams,
		IncludeSummary: in.IncludeSummary,
		CurrentStep:    "任务创建",
		MaxRetries:     3,
		CreatedAt:      time.Now(),
	}

	//5.保存任务数据
	taskData := map[string]interface{}{
		"order_type": in.OrderType,
		"user_id":    in.UserId,
		"start_time": in.StartTime,
		"end_time":   in.EndTime,
	}
	if taskDataBytes, err := json.Marshal(taskData); err == nil {
		task.TaskData = string(taskDataBytes)
	}

	if err = task.Create(); err != nil {
		return nil, fmt.Errorf("创建任务失败:%v", err)
	}

	//6.发送任务到消息队列
	if err = sendTaskToQueue(task, in); err != nil {
		task.UpdateStatus(3, "任务提交失败"+err.Error())
		return nil, err
	}
	return task, nil
}

// 创建导出任务（发布者）
func CreateExportTask(in *__.ExportOrderReq) (*models.ExportTask, error) {
	// 使用优化版本
	return CreateExportTaskV2(in)
}

// 参数校验
func validateExportRequest(in *__.ExportOrderReq) error {
	if in.UserId <= 0 {
		return errors.New("用户ID不能为空")
	}
	if in.StartTime == "" || in.EndTime == "" {
		return errors.New("开始时间和结束时间不能为空")
	}
	if in.OrderType < 0 {
		return errors.New("订单类型不能为负数")
	}
	return nil
}

// 解析时间范围
func parseTimeRange(startTimeStr, endTimeStr string) (time.Time, time.Time, error) {
	startTime, err := parseTimeF(startTimeStr)
	if err != nil {
		return time.Time{}, time.Time{}, fmt.Errorf("解析开始时间失败: %v", err)
	}

	endTime, err := parseTimeF(endTimeStr)
	if err != nil {
		return time.Time{}, time.Time{}, fmt.Errorf("解析结束时间失败: %v", err)
	}

	if startTime.After(endTime) {
		return time.Time{}, time.Time{}, errors.New("开始时间不能晚于结束时间")
	}

	return startTime, endTime, nil
}

// 解析时间（支持多种格式）
func parseTimeF(timeStr string) (time.Time, error) {
	formats := []string{
		time.RFC3339,
		"2006-01-02 15:04:05",
		"2006-01-02",
		"2006-01-02T15:04:05",
	}

	for _, format := range formats {
		if t, err := time.Parse(format, timeStr); err == nil {
			return t, nil
		}
	}

	return time.Time{}, fmt.Errorf("无法解析时间格式: %s", timeStr)
}

// 检查数据量限制
func checkDataVolumeLimit(startTime, endTime time.Time, orderType int8, maxRecords int32) error {
	// 查询符合条件的记录数
	var count int64
	query := config.DB.Model(&models.Orders{}).
		Where("create_at BETWEEN ? AND ?", startTime, endTime).
		Where("order_type = ?", orderType)

	if err := query.Count(&count).Error; err != nil {
		return fmt.Errorf("查询数据量失败: %v", err)
	}

	// 检查是否超过最大记录数限制
	if maxRecords > 0 && count > int64(maxRecords) {
		return fmt.Errorf("数据量超过限制: %d > %d", count, maxRecords)
	}

	// 检查系统默认限制（100万条）
	const maxSystemRecords = 1000000
	if count > maxSystemRecords {
		return fmt.Errorf("数据量过大，超过系统限制: %d > %d", count, maxSystemRecords)
	}

	return nil
}

// 获取导出格式
func getExportFormat(format string) string {
	if format == "" {
		return "excel"
	}
	validFormats := []string{"excel", "csv", "pdf"}
	for _, validFormat := range validFormats {
		if format == validFormat {
			return format
		}
	}
	return "excel"
}

// 获取优先级
func getPriority(priority int32) uint8 {
	if priority <= 0 || priority > 3 {
		return 2 // 默认普通优先级
	}
	return uint8(priority)
}

// 发送任务到消息队列
func sendTaskToQueue(task *models.ExportTask, req *__.ExportOrderReq) error {
	taskMsg, err := json.Marshal(map[string]interface{}{
		"task_id":           task.TaskId,
		"user_id":           task.UserId,
		"start_time":        req.StartTime,
		"end_time":          req.EndTime,
		"order_type":        req.OrderType,
		"export_format":     req.ExportFormat,
		"enable_encryption": req.EnableEncryption,
		"include_summary":   req.IncludeSummary,
		"max_records":       req.MaxRecords,
		"filter_params":     req.FilterParams,
		"priority":          req.Priority,
	})

	if err != nil {
		return fmt.Errorf("序列化任务消息失败:%v", err)
	}

	//使用现有的rabbitMQ组件
	mq := inits.NewRabbitMQSimple("order_export_queue")
	defer mq.Destory()

	//发送消息
	success, err := mq.PublishSimple(taskMsg)
	if !success || err != nil {
		return fmt.Errorf("发送任务到队列失败:%v", err)
	}

	return nil
}

// 获取导出任务状态（优化版）
func GetExportTaskStatusV2(taskId string) (*models.ExportTask, error) {
	var task models.ExportTask
	err := config.DB.Where("task_id = ?", taskId).First(&task).Error
	if err != nil {
		return nil, fmt.Errorf("查询任务失败: %v", err)
	}
	return &task, nil
}

// 获取导出任务列表
func GetExportTaskListOrder(userId uint32, page, pageSize int, status uint32, startDate, endDate string) ([]*models.ExportTask, int32, error) {
	return models.GetExportTaskList(userId, page, pageSize, status, startDate, endDate)
}

// 删除导出任务
func DeleteExportTaskOrder(taskId string, userId uint32) error {
	return models.DeleteExportTask(taskId, userId)
}

// 下载导出文件
func DownloadExportFileOrder(taskId string, userId uint32) (*models.ExportTask, error) {
	task, err := GetExportTaskStatusV2(taskId)
	if err != nil {
		return nil, err
	}

	// 检查用户权限
	if task.UserId != userId {
		return nil, errors.New("无权限访问该任务")
	}

	// 检查任务状态
	if task.Status != 2 {
		return nil, errors.New("任务未完成，无法下载")
	}

	return task, nil
}

// 获取导出进度
func GetExportProgressOrder(taskId string, userId uint32) (*models.ExportTask, error) {
	task, err := GetExportTaskStatusV2(taskId)
	if err != nil {
		return nil, err
	}

	// 检查用户权限
	if task.UserId != userId {
		return nil, errors.New("无权限访问该任务")
	}

	return task, nil
}

// 重试失败任务
func RetryFailedTask(taskId string, userId uint32) error {
	return models.RetryFailedTask(taskId, userId)
}

// 获取任务统计信息
func GetTaskStatistics(userId uint32, startDate, endDate string) (map[string]interface{}, error) {
	return models.GetTaskStatistics(userId, startDate, endDate)
}

// 清理过期任务
func CleanExpiredTasks(days int) error {
	return models.CleanExpiredTasks(days)
}

// getOrderDataForExcel 获取用于Excel导出的订单数据
func getOrderDataForExcel(startTime, endTime time.Time, orderType int8) ([]untils.OrderData, error) {
	// 构建查询
	sqlQuery := `
		SELECT 
			orders.order_sn, 
			orders.user_id, 
			orders.driver_id, 
			orders.order_type, 
			orders.price, 
			orders.create_at, 
			orders.order_status 
		FROM 
			orders 
		WHERE create_at BETWEEN ? AND ? AND order_type = ?
		ORDER BY create_at DESC
	`

	// 执行查询
	var results []struct {
		OrderSn     string    `gorm:"column:order_sn"`
		UserId      uint32    `gorm:"column:user_id"`
		DriverId    uint32    `gorm:"column:driver_id"`
		OrderType   int8      `gorm:"column:order_type"`
		Price       float64   `gorm:"column:price"`
		CreateAt    time.Time `gorm:"column:create_at"`
		OrderStatus int8      `gorm:"column:order_status"`
	}

	if err := config.DB.Raw(sqlQuery, startTime, endTime, orderType).Scan(&results).Error; err != nil {
		return nil, fmt.Errorf("查询订单数据失败: %v", err)
	}

	// 转换为Excel导出格式
	var orderData []untils.OrderData
	for _, result := range results {
		orderData = append(orderData, untils.OrderData{
			OrderSn:     result.OrderSn,
			UserId:      result.UserId,
			DriverId:    result.DriverId,
			OrderType:   result.OrderType,
			Price:       result.Price,
			CreateAt:    result.CreateAt,
			OrderStatus: result.OrderStatus,
		})
	}

	return orderData, nil
}

// 获取导出任务状态
func GetExportTaskStatusOrder(taskId string) (*models.ExportTask, error) {
	var task models.ExportTask
	// 根据任务ID和用户ID查询任务
	err := config.DB.Where("task_id = ?", taskId).First(&task).Error
	if err != nil {
		return nil, err
	}
	return &task, nil
}
